/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG                        *
*Copyright (C) 2006, Tony Sparks                                                     *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "DialogModel.h"
#include "../Kernel.h"

extern Kernel* g_kernel;

#define PRINT( str ) (g_kernel->LPrintf( str ))


/*------------------------------------------------------------------
    Dialog Tree
-------------------------------------------------------------------*/

DialogTree::DialogTree()
{
    m_talkedWith = false;
    // m_text       = "";
}

/** User made a decision, now return the response tree */
DialogTree* DialogTree::Respond( const std::string &response )
{   
    if ( m_dialog.find( response ) != m_dialog.end() )
    {
        return m_dialog[ response ];
    }
    return NULL;
}

DialogTree::~DialogTree()
{
    type_DialogNode::iterator it = m_dialog.begin();
    for ( ;it != m_dialog.end(); it++ )
    {   
        if ( it->second ) {
            
            delete it->second;
        }
    }
    m_dialog.clear();
}




/*---------------------------------------------------------------------------------------
    Dialog Model
----------------------------------------------------------------------------------------*/


MModel::MModel(void)
{
    m_active        = false;
    m_currentDialog = NULL;
    m_root          = NULL;
    //m_text          = "";
    m_index         = 0;
}

MModel::~MModel(void)
{
    Clear();
}

/** Clear the dialog box */
void MModel::Clear()
{
    if ( m_root )   delete m_root;
    m_root          = NULL;
    m_currentDialog = NULL;
    m_active        = false;
    m_text.clear();
    m_index         = 0;
}

/** Set the current Dialog node */
void MModel::SetDialogTree( DialogTree* current ) 
{ 
    m_currentDialog = current; 
    if ( m_currentDialog )
        SetText( m_currentDialog->GetText() );
}

/** Load a conversation from a file */
bool MModel::LoadDialog( const std::string &fileName )
{
    MFile file;
    if ( file.Open( fileName ) ) {
        g_kernel->LPrintf( ("ERROR loading: " + fileName).c_str() );
        return true;
    }
    // read the version type
    std::string version = file.ReadLine();
    
    // TODO -varify it is the current version

    // delete any other dialog
    Clear();
    // Start creating the parse tree
    m_root = new DialogTree;
    SetDialogTree ( ReadDialog( m_root, file ) );
    return false;
}

/** Recusevily read the dialog tree */
DialogTree* MModel::ReadDialog( DialogTree* root, MFile &f )
{
    // first check if there is more file 
    if ( f.IsEnd() )
        return NULL;

    // get the amount of response options
    int amt = f.ReadInt();
    // read the display text for this node
    std::string txt = f.ReadNext(":" );

    root->SetText ( txt );
    
    DialogTree* node = NULL;
    for (int i = 0; i < amt && !f.IsEnd(); i++ )
    {
        node = new DialogTree;
        
        DialogResponse::MissionResponse mResponse;
        // get a response
        std::string response = f.ReadNext(":");
        // get the mission name if one -- NOTE: 'null' is
        // a keyword for no mission
        std::string mission = f.ReadNext(":");

        mResponse.hasMission    = !(mission == "null");
        mResponse.mission_name  = mission;
        mResponse.response      = response;

        // now build the subtree for this response
        root->SetDialogTree( mResponse, ReadDialog( node, f ) );
    }
    return root;
}

/** Set the current response Option */
void MModel::SelectNextResponse()
{
    ++m_index;
    if ( m_index >= GetResponses()->size )
        m_index = (GetResponses()->size == 0) ? 0 : GetResponses()->size-1;
}

/** Get the prev response */
void MModel::SelectPrevResponse()
{
    --m_index;
    if ( m_index < 0 )
        m_index =  0;
}